package com.swak.reactivex.transport;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;

import com.swak.exception.RemotingException;
import com.swak.registry.URL;

public class ReferenceCountExchangeClient implements ExchangeClient {

	private final AtomicInteger referenceCount = new AtomicInteger(0);
	private ExchangeClient client;

	public ReferenceCountExchangeClient(ExchangeClient client) {
		this.client = client;
		this.referenceCount.incrementAndGet();
	}

	@Override
	public void connect() throws RemotingException {
		client.connect();
	}

	@Override
	public void close() {
		if (referenceCount.decrementAndGet() <= 0) {
			client.close();
		}
	}

	@Override
	public boolean isClosed() {
		return client.isClosed();
	}

	@Override
	public URL url() {
		return client.url();
	}

	@Override
	public boolean isConnected() {
		return client.isConnected();
	}

	@Override
	public void send(Object message, boolean sent) throws RemotingException {
		client.send(message, sent);
	}

	@Override
	public void sendFile(File file, boolean sent) throws RemotingException, FileNotFoundException {
		client.sendFile(file, sent);
	}

	@Override
	public InetSocketAddress localAddress() {
		return client.localAddress();
	}

	@Override
	public InetSocketAddress remoteAddress() {
		return client.remoteAddress();
	}

	@Override
	public boolean hasAttribute(String key) {
		return client.hasAttribute(key);
	}

	@Override
	public Object getAttribute(String key) {
		return client.getAttribute(key);
	}

	@Override
	public void setAttribute(String key, Object value) {
		client.setAttribute(key, value);
	}

	@Override
	public void removeAttribute(String key) {
		client.removeAttribute(key);
	}

	@Override
	public CompletableFuture<Object> request(Object request) throws RemotingException {
		return client.request(request);
	}

	@Override
	public CompletableFuture<Object> request(Object request, int timeout) throws RemotingException {
		return client.request(request, timeout);
	}

	/**
	 * The reference count of current ExchangeClient, connection will be closed if
	 * all invokers destroyed.
	 */
	public void incrementAndGetCount() {
		referenceCount.incrementAndGet();
	}
}
